home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Games Collection 1 / software vault.zip / software vault / CDR10 / XLIB06.ZIP / XPBITMAP.ASM < prev    next >
Assembly Source File  |  1993-09-13  |  25KB  |  603 lines

  1. ;-----------------------------------------------------------------------
  2. ; MODULE XPBITMAP
  3. ;
  4. ; Planar Bitmap functions - System Ram <-> Video Ram
  5. ;
  6. ; Compile with Tasm.
  7. ; C callable.
  8. ;
  9. ;
  10. ; ****** XLIB - Mode X graphics library                ****************
  11. ; ******                                               ****************
  12. ; ****** Written By Themie Gouthas                     ****************
  13. ;
  14. ; egg@dstos3.dsto.gov.au
  15. ; teg@bart.dsto.gov.au
  16. ;-----------------------------------------------------------------------
  17.  
  18.  
  19. COMMENT $
  20.  
  21.   This module implements a set of functions to operate on planar bitmaps.
  22.   Planar bitmaps as used by these functions have the following structure:
  23.  
  24.   BYTE 0                 The bitmap width in bytes (4 pixel groups) range 1..255
  25.   BYTE 1                 The bitmap height in rows range 1..255
  26.   BYTE 2..n1             The plane 0 pixels width*height bytes
  27.   BYTE n1..n2            The plane 1 pixels width*height bytes
  28.   BYTE n2..n3            The plane 2 pixels width*height bytes
  29.   BYTE n3..n4            The plane 3 pixels width*height bytes
  30.  
  31.   These functions provide the fastest possible bitmap blts from system ram to
  32.   to video and further, the single bitmap is applicable to all pixel
  33.   allignments. The masked functions do not need separate masks since all non
  34.   zero pixels are considered to be masking pixels, hence if a pixel is 0 the
  35.   corresponding screen destination pixel is left unchanged.
  36.  
  37.  
  38. $
  39.  
  40. include xlib.inc
  41. include xpbitmap.inc
  42. LOCALS
  43.     .code
  44.  
  45. ;----------------------------------------------------------------------
  46. ; x_flip_masked_pbm - mask write a planar bitmap from system ram to video ram
  47. ; all zero source bitmap bytes indicate destination byte to be left unchanged
  48. ; If "Orientation" is set then the bitmap is flipped from left to right as
  49. ; it is drawn
  50. ;
  51. ; Source Bitmap structure:
  52. ;
  53. ;  Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  54. ;  Bitmap data (plane 2)..,Bitmap data (plane 3)..
  55. ;
  56. ;  note width is in bytes ie lots of 4 pixels
  57. ;
  58. ;  x_flip_masked_pbm(X,Y,ScrnOffs,char far * Bitmap, Orientation)
  59. ;
  60. ;
  61. ; LIMITATIONS: No clipping is supported
  62. ;              Only supports bitmaps with widths which are a multiple of
  63. ;              4 pixels
  64. ;
  65. ; Written by Themie Gouthas
  66. ;----------------------------------------------------------------------
  67. _x_flip_masked_pbm  proc
  68.         ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word
  69.     LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk
  70.     push  bp
  71.         mov   bp,sp
  72.     sub   sp,LocalStk                 ; Create space for local variables
  73.         push  si
  74.         push  di
  75.     push  ds
  76.     cld
  77.         mov   ax,SCREEN_SEG
  78.         mov   es,ax
  79.         mov   ax,[Y]                      ; Calculate dest screen row
  80.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  81.     mul   bx                          ;  width then adding screen offset
  82.         mov   di,[ScrnOffs]               ;  store result in DI
  83.         add   di,ax
  84.         mov   cx,[X]                      ; Load X coord into CX and make a
  85.     mov   dx,cx                       ;  copy in DX
  86.     shr   dx,2                        ; Find starting byte in dest row
  87.     add   di,dx                       ;  add to DI giving screen offset of
  88.                                           ;  first pixel's byte
  89.         lds   si,[Bitmap]                 ; DS:SI -> Bitmap data
  90.         lodsw                             ; Al = B.M. width (bytes) AH = B.M.
  91.                                           ;  height
  92.         cmp   Orientation,0
  93.         jz    UnFlippedMasked
  94.  
  95.     mov   [BMHeight],ah               ; Save source bitmap dimensions
  96.         xor   ah,ah                       ; LineInc = bytes to the begin.
  97.     add   bx,ax                       ;  of bitmaps next row on screen
  98.     mov   [LineInc],bx
  99.     mov   bh,al                       ; Use bh as column loop count
  100.         and   cx,0003h                    ; mask X coord giving plane of 1st
  101.                       ; bitmap pixel(zero CH coincidentally)
  102.     mov   ah,11h                      ; Init. mask for VGA plane selection
  103.         shl   ah,cl                       ; Shift for starting pixel plane
  104.         mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  105.         mov   al,MAP_MASK
  106.         out   dx,al
  107.         inc   dx
  108.     mov   [Plane],4                   ; Set plane counter to 4
  109. @@PlaneLoop:
  110.         push  di                          ; Save bitmap's start dest. offset
  111.         mov   bl,[BMHeight]               ; Reset row counter (BL)
  112.         mov   al,ah
  113.         out   dx,al                       ; set vga write plane
  114. @@RowLoop:
  115.     mov   cl,bh                       ; Reset Column counter cl
  116. @@ColLoop:
  117.     lodsb                             ; Get next source bitmap byte
  118.     or    al,al                       ; If not zero then write to dest.
  119.     jz    @@NoPixel                   ; otherwise skip to next byte
  120.     mov   es:[di],al
  121. @@NoPixel:
  122.     dec   di
  123.     loop  @@ColLoop                   ; loop if more columns left
  124.     add   di,[LineInc]                ; Move to next row
  125.         dec   bl                          ; decrement row counter
  126.         jnz   @@RowLoop                   ; Jump if more rows left
  127.         pop   di                          ; Restore bitmaps start dest byte
  128.         ror   ah,1                        ; Shift mask for next plane
  129.     sbb   di,0                        ; If wrapped increment dest address
  130.     dec   [Plane]                     ; Decrement plane counter
  131.         jnz   @@PlaneLoop                 ; Jump if more planes left
  132.  
  133.         pop   ds                          ; restore data segment
  134.         pop   di                          ; restore registers
  135.         pop   si
  136.         mov   sp,bp                       ; dealloc local variables
  137.         pop   bp
  138.         ret
  139. _x_flip_masked_pbm  endp
  140.  
  141.  
  142. ;----------------------------------------------------------------------
  143. ; x_put_masked_pbm - mask write a planar bitmap from system ram to video ram
  144. ; all zero source bitmap bytes indicate destination byte to be left unchanged
  145. ;
  146. ; Source Bitmap structure:
  147. ;
  148. ;  Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  149. ;  Bitmap data (plane 2)..,Bitmap data (plane 3)..
  150. ;
  151. ;  note width is in bytes ie lots of 4 pixels
  152. ;
  153. ;  x_put_masked_pbm(X,Y,ScrnOffs,char far * Bitmap)
  154. ;
  155. ;
  156. ; LIMITATIONS: No clipping is supported
  157. ;              Only supports bitmaps with widths which are a multiple of
  158. ;              4 pixels
  159. ;
  160. ; Written by Themie Gouthas
  161. ;----------------------------------------------------------------------
  162. _x_put_masked_pbm  proc
  163.         ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  164.     LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk
  165.     push  bp
  166.         mov   bp,sp
  167.     sub   sp,LocalStk                 ; Create space for local variables
  168.         push  si
  169.         push  di
  170.     push  ds
  171.     cld
  172.         mov   ax,SCREEN_SEG
  173.         mov   es,ax
  174.         mov   ax,[Y]                      ; Calculate dest screen row
  175.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  176.     mul   bx                          ;  width then adding screen offset
  177.         mov   di,[ScrnOffs]               ;  store result in DI
  178.         add   di,ax
  179.         mov   cx,[X]                      ; Load X coord into CX and make a
  180.     mov   dx,cx                       ;  copy in DX
  181.     shr   dx,2                        ; Find starting byte in dest row
  182.     add   di,dx                       ;  add to DI giving screen offset of
  183.                                           ;  first pixel's byte
  184.         lds   si,[Bitmap]                 ; DS:SI -> Bitmap data
  185.         lodsw                             ; Al = B.M. width (bytes) AH = B.M.
  186.                                           ;  height
  187. UnFlippedMasked:
  188.     mov   [BMHeight],ah               ; Save source bitmap dimensions
  189.         xor   ah,ah                       ; LineInc = bytes to the begin.
  190.     sub   bx,ax                       ;  of bitmaps next row on screen
  191.     mov   [LineInc],bx
  192.     mov   bh,al                       ; Use bh as column loop count
  193.         and   cx,0003h                    ; mask X coord giving plane of 1st
  194.                       ; bitmap pixel(zero CH coincidentally)
  195.     mov   ah,11h                      ; Init. mask for VGA plane selection
  196.         shl   ah,cl                       ; Shift for starting pixel plane
  197.         mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  198.         mov   al,MAP_MASK
  199.         out   dx,al
  200.         inc   dx
  201.     mov   [Plane],4                   ; Set plane counter to 4
  202. @@PlaneLoop:
  203.         push  di                          ; Save bitmap's start dest. offset
  204.         mov   bl,[BMHeight]               ; Reset row counter (BL)
  205.         mov   al,ah
  206.         out   dx,al                       ; set vga write plane
  207. @@RowLoop:
  208.     mov   cl,bh                       ; Reset Column counter cl
  209. @@ColLoop:
  210.     lodsb                             ; Get next source bitmap byte
  211.     or    al,al                       ; If not zero then write to dest.
  212.     jz    @@NoPixel                   ; otherwise skip to next byte
  213.     mov   es:[di],al
  214. @@NoPixel:
  215.     inc   di
  216.     loop  @@ColLoop                   ; loop if more columns left
  217.     add   di,[LineInc]                ; Move to next row
  218.         dec   bl                          ; decrement row counter
  219.         jnz   @@RowLoop                   ; Jump if more rows left
  220.         pop   di                          ; Restore bitmaps start dest byte
  221.         rol   ah,1                        ; Shift mask for next plane
  222.     adc   di,0                        ; If wrapped increment dest address
  223.     dec   [Plane]                     ; Decrement plane counter
  224.         jnz   @@PlaneLoop                 ; Jump if more planes left
  225.  
  226.         pop   ds                          ; restore data segment
  227.         pop   di                          ; restore registers
  228.         pop   si
  229.         mov   sp,bp                       ; dealloc local variables
  230.         pop   bp
  231.         ret
  232. _x_put_masked_pbm  endp
  233.  
  234.  
  235.  
  236. ;----------------------------------------------------------------------
  237. ; x_put_pbm - Write a planar bitmap from system ram to video ram
  238. ;
  239. ; Source Bitmap structure:
  240. ;
  241. ;  Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  242. ;  Bitmap data (plane 2)..,Bitmap data (plane 3)..
  243. ;
  244. ;  note width is in bytes ie lots of 4 pixels
  245. ;
  246. ;  x_put_pbm(X,Y,ScrnOffs,char far * Bitmap)
  247. ;
  248. ;
  249. ; LIMITATIONS: No clipping is supported
  250. ;              Only supports bitmaps with widths which are a multiple of
  251. ;              4 pixels
  252. ; FEATURES   : Automatically selects REP MOVSB or REP MOVSW  depending on
  253. ;              source bitmap width, by modifying opcode ;-).
  254. ;
  255. ; Written by Themie Gouthas
  256. ;----------------------------------------------------------------------
  257.  
  258.  
  259. _x_put_pbm  proc
  260.     ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword
  261.     LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk
  262.     push  bp
  263.         mov   bp,sp
  264.     sub   sp,LocalStk                 ; Create space for local variables
  265.     push  si
  266.         push  di
  267.     push  ds
  268.     cld
  269.         mov   ax,SCREEN_SEG
  270.         mov   es,ax
  271.         mov   ax,[Y]                      ; Calculate dest screen row
  272.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  273.     mul   bx                          ;  width then adding screen offset
  274.         mov   di,[ScrnOffs]               ;  store result in DI
  275.         add   di,ax
  276.         mov   cx,[X]                      ; Load X coord into CX and make a
  277.     mov   dx,cx                       ;  copy in DX
  278.     shr   dx,2                        ; Find starting byte in dest row
  279.     add   di,dx                       ;  add to DI giving screen offset of
  280.                                           ;  first pixel's byte
  281.         lds   si,[Bitmap]                 ; DS:SI -> Bitmap data
  282.         lodsw                             ; Al = B.M. width (bytes) AH = B.M.
  283.                                           ;  height
  284. UnFlipped:
  285.         mov   [BMHeight],ah               ; Save source bitmap dimensions
  286.         xor   ah,ah                       ; LineInc = bytes to the begin.
  287.     sub   bx,ax                       ;  of bitmaps next row on screen
  288.     mov   [LineInc],bx
  289.     mov   bh,al
  290.                       ; Self Modifying, Shame, shame shame..
  291.         and   cx,0003h                    ; mask X coord giving plane of 1st
  292.                                           ; bitmap pixel(zero CH coincidentally)
  293.     mov   ah,11h                      ; Init. mask for VGA plane selection
  294.         shl   ah,cl                       ; Shift for starting pixel plane
  295.         mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  296.         mov   al,MAP_MASK
  297.         out   dx,al
  298.         inc   dx
  299.     mov   [Plane],4                   ; Set plane counter to 4
  300. @@PlaneLoop:
  301.         push  di
  302.     mov   bl,[BMHeight]
  303.         mov   al,ah
  304.         out   dx,al
  305. @@RowLoop:
  306.     mov   cl,bh
  307.     shr   cl,1
  308.     rep   movsw                       ; Copy a complete row for curr plane
  309.     adc   cl,0
  310.     rep   movsb
  311.     add   di,[LineInc]                ; Move to next row
  312.         dec   bl                          ; decrement row counter
  313.         jnz   @@RowLoop                   ; Jump if more rows left
  314.         pop   di                          ; Restore bitmaps start dest byte
  315.         rol   ah,1                        ; Shift mask for next plane
  316.     adc   di,0                        ; If wrapped increment dest address
  317.     dec   [Plane]                     ; Decrement plane counter
  318.         jnz   @@PlaneLoop                 ; Jump if more planes left
  319.  
  320.         pop   ds                          ; restore data segment
  321.         pop   di                          ; restore registers
  322.         pop   si
  323.         mov   sp,bp                       ; dealloc local variables
  324.         pop   bp
  325.         ret
  326. _x_put_pbm  endp
  327.  
  328. ;----------------------------------------------------------------------
  329. ; x_flip_pbm - Write a planar bitmap from system ram to video ram
  330. ; If "Orientation" is set then the bitmap is flipped from left to right as
  331. ; it is drawn
  332.  
  333. ;
  334. ; Source Bitmap structure:
  335. ;
  336. ;  Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  337. ;  Bitmap data (plane 2)..,Bitmap data (plane 3)..
  338. ;
  339. ;  note width is in bytes ie lots of 4 pixels
  340. ;
  341. ;  x_flip_pbm(X,Y,ScrnOffs,char far * Bitmap, WORD orientation)
  342. ;
  343. ;
  344. ; LIMITATIONS: No clipping is supported
  345. ;              Only supports bitmaps with widths which are a multiple of
  346. ;              4 pixels
  347. ;
  348. ; NOTES: The flipped put function is slower than the standard put function
  349. ;
  350. ; Written by Themie Gouthas
  351. ;----------------------------------------------------------------------
  352. _x_flip_pbm  proc
  353.         ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word
  354.     LOCAL Plane:byte,BMHeight:byte,LineInc:word=LocalStk
  355.     push  bp
  356.         mov   bp,sp
  357.     sub   sp,LocalStk                 ; Create space for local variables
  358.         push  si
  359.         push  di
  360.     push  ds
  361.     cld
  362.         mov   ax,SCREEN_SEG
  363.         mov   es,ax
  364.         mov   ax,[Y]                      ; Calculate dest screen row
  365.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  366.     mul   bx                          ;  width then adding screen offset
  367.         mov   di,[ScrnOffs]               ;  store result in DI
  368.         add   di,ax
  369.         mov   cx,[X]                      ; Load X coord into CX and make a
  370.     mov   dx,cx                       ;  copy in DX
  371.     shr   dx,2                        ; Find starting byte in dest row
  372.     add   di,dx                       ;  add to DI giving screen offset of
  373.                                           ;  first pixel's byte
  374.         lds   si,[Bitmap]                 ; DS:SI -> Bitmap data
  375.         lodsw                             ; Al = B.M. width (bytes) AH = B.M.
  376.                                           ;  height
  377.         cmp   Orientation,0
  378.         jz    UnFlipped
  379.  
  380.     mov   [BMHeight],ah               ; Save source bitmap dimensions
  381.         xor   ah,ah                       ; LineInc = bytes to the begin.
  382.     add   bx,ax                       ;  of bitmaps next row on screen
  383.     mov   [LineInc],bx
  384.     mov   bh,al                       ; Use bh as column loop count
  385.         and   cx,0003h                    ; mask X coord giving plane of 1st
  386.                       ; bitmap pixel(zero CH coincidentally)
  387.     mov   ah,11h                      ; Init. mask for VGA plane selection
  388.         shl   ah,cl                       ; Shift for starting pixel plane
  389.         mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  390.         mov   al,MAP_MASK
  391.         out   dx,al
  392.         inc   dx
  393.     mov   [Plane],4                   ; Set plane counter to 4
  394. @@PlaneLoop:
  395.         push  di                          ; Save bitmap's start dest. offset
  396.         mov   bl,[BMHeight]               ; Reset row counter (BL)
  397.         mov   al,ah
  398.         out   dx,al                       ; set vga write plane
  399. @@RowLoop:
  400.     mov   cl,bh                       ; Reset Column counter cl
  401. @@ColLoop:
  402.         lodsb
  403.         mov   es:[di],al
  404.         dec   di
  405.         sub   di,2
  406.     loop  @@ColLoop                   ; loop if more columns left
  407. @@DoneCol:
  408.     add   di,[LineInc]                ; Move to next row
  409.         dec   bl                          ; decrement row counter
  410.         jnz   @@RowLoop                   ; Jump if more rows left
  411.         pop   di                          ; Restore bitmaps start dest byte
  412.         ror   ah,1                        ; Shift mask for next plane
  413.     sbb   di,0                        ; If wrapped increment dest address
  414.     dec   [Plane]                     ; Decrement plane counter
  415.         jnz   @@PlaneLoop                 ; Jump if more planes left
  416.  
  417.         pop   ds                          ; restore data segment
  418.         pop   di                          ; restore registers
  419.         pop   si
  420.         mov   sp,bp                       ; dealloc local variables
  421.         pop   bp
  422.         ret
  423. _x_flip_pbm  endp
  424.  
  425.  
  426. ;----------------------------------------------------------------------
  427. ; x_get_pbm - Read a planar bitmap to system ram from video ram
  428. ;
  429. ; Source Bitmap structure:
  430. ;
  431. ;  Width:byte, Height:byte, Bitmap data (plane 0)...Bitmap data (plane 1)..,
  432. ;  Bitmap data (plane 2)..,Bitmap data (plane 3)..
  433. ;
  434. ;  note width is in bytes ie lots of 4 pixels
  435. ;
  436. ;  x_get_pbm(X,Y,BMwidth,BMheight,ScrnOffs,char far * Bitmap)
  437. ;
  438. ;
  439. ; LIMITATIONS: No clipping is supported
  440. ;              Only supports bitmaps with widths which are a multiple of
  441. ;              4 pixels
  442. ; FEATURES   : Automatically selects REP MOVSB or REP MOVSW  depending on
  443. ;              source bitmap width, by modifying opcode ;-).
  444. ;
  445. ; Written by Themie Gouthas
  446. ;----------------------------------------------------------------------
  447. _x_get_pbm  proc
  448.     ARG X:word,Y:word,SrcWidth:byte,SrcHeight:byte,ScrnOffs:word,Bitmap:dword
  449.     LOCAL Plane:byte,LineInc:word=LocalStk
  450.     push  bp
  451.         mov   bp,sp
  452.     sub   sp,LocalStk                 ; Create space for local variables
  453.         push  si
  454.         push  di
  455.         push  ds
  456.     cld
  457.  
  458.     mov   ax,[Y]                      ; Calculate screen row
  459.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. Y coord by Screen
  460.     mul   bx                          ;  width then adding screen offset
  461.     mov   si,[ScrnOffs]               ;  store result in SI
  462.     add   si,ax
  463.         mov   cx,[X]                      ; Load X coord into CX and make a
  464.     mov   dx,cx                       ;  copy in DX
  465.     shr   dx,2                        ; Find starting byte in screen row
  466.     add   si,dx                       ;  add to SI giving screen offset of
  467.                       ;  first pixel's byte
  468.     mov   ax,SCREEN_SEG
  469.     mov   ds,ax
  470.     les   di,[Bitmap]                 ; ES:DI -> Bitmap data
  471.     mov   al,[SrcWidth]
  472.     mov   ah,[SrcHeight]
  473.     stosw                             ; Al = B.M. width (bytes) AH = B.M.
  474.                                           ;  height
  475.         xor   ah,ah                       ; LineInc = bytes to the begin.
  476.     sub   bx,ax                       ;  of bitmaps next row on screen
  477.     mov   [LineInc],bx
  478.     mov   bh,al
  479.                       ; Self Modifying, Shame, shame shame..
  480.         and   cx,0003h                    ; mask X coord giving plane of 1st
  481.                                           ; bitmap pixel(zero CH coincidentally)
  482.     mov   ah,11h                      ; Init. mask for VGA plane selection
  483.     shl   ah,cl                       ; Shift for starting pixel plane
  484.     mov   dx,GC_INDEX                 ; Prepare VGA for cpu to video reads
  485.     mov   al,READ_MAP
  486.         out   dx,al
  487.         inc   dx
  488.     mov   [Plane],4                   ; Set plane counter (BH) to 4
  489.     mov   al,cl
  490. @@PlaneLoop:
  491.     push  si
  492.     mov   bl,[SrcHeight]
  493.         out   dx,al
  494. @@RowLoop:
  495.     mov   cl,bh
  496.     shr   cl,1
  497.     rep   movsw                       ; Copy a complete row for curr plane
  498.     adc   cl,0
  499.     rep   movsb
  500.     add   si,[LineInc]                ; Move to next row
  501.         dec   bl                          ; decrement row counter
  502.         jnz   @@RowLoop                   ; Jump if more rows left
  503.     pop   si                          ; Restore bitmaps start dest byte
  504.  
  505.     inc   al                          ; Select next plane to read from
  506.     and   al,3                        ;
  507.  
  508.     rol   ah,1                        ; Shift mask for next plane
  509.     adc   si,0                        ; If wrapped increment dest address
  510.     dec   [Plane]                     ; Decrement plane counter
  511.     jnz   @@PlaneLoop                 ; Jump if more planes left
  512.  
  513.         pop   ds                          ; restore data segment
  514.         pop   di                          ; restore registers
  515.         pop   si
  516.         mov   sp,bp                       ; dealloc local variables
  517.         pop   bp
  518.         ret
  519. _x_get_pbm  endp
  520.  
  521.  
  522.  
  523.  
  524.     end
  525.  
  526.  
  527.  
  528.         ARG X:word,Y:word,ScrnOffs:word,Bitmap:dword,Orientation:word
  529.     LOCAL Plane:byte,BMHeight:byte,LineInc:word,Columns:byte=LocalStk
  530.     push  bp
  531.         mov   bp,sp
  532.     sub   sp,LocalStk                 ; Create space for local variables
  533.         push  si
  534.         push  di
  535.     push  ds
  536.     cld
  537.         mov   ax,SCREEN_SEG
  538.         mov   es,ax
  539.         mov   ax,[Y]                      ; Calculate dest screen row
  540.     mov   bx,[_ScrnLogicalByteWidth]  ;  by mult. dest Y coord by Screen
  541.     mul   bx                          ;  width then adding screen offset
  542.         mov   di,[ScrnOffs]               ;  store result in DI
  543.         add   di,ax
  544.         mov   cx,[X]                      ; Load X coord into CX and make a
  545.     mov   dx,cx                       ;  copy in DX
  546.     shr   dx,2                        ; Find starting byte in dest row
  547.     add   di,dx                       ;  add to DI giving screen offset of
  548.                                           ;  first pixel's byte
  549.         lds   si,[Bitmap]                 ; DS:SI -> Bitmap data
  550.         lodsw                             ; Al = B.M. width (bytes) AH = B.M.
  551.                                           ;  height
  552.         cmp   Orientation,0
  553.         jz    UnFlipped
  554.  
  555.     mov   [BMHeight],ah               ; Save source bitmap dimensions
  556.         xor   ah,ah                       ; LineInc = bytes to the begin.
  557.     add   bx,ax                       ;  of bitmaps next row on screen
  558.     mov   [LineInc],bx
  559.     mov   [Columns],al                ; Use bh as column loop count
  560.         and   cx,0003h                    ; mask X coord giving plane of 1st
  561.                       ; bitmap pixel(zero CH coincidentally)
  562.     mov   ah,11h                      ; Init. mask for VGA plane selection
  563.         shl   ah,cl                       ; Shift for starting pixel plane
  564.         mov   bh,ah
  565.         mov   dx,SC_INDEX                 ; Prepare VGA for cpu to video writes
  566.         mov   al,MAP_MASK
  567.         out   dx,al
  568.         inc   dx
  569.     mov   [Plane],4                   ; Set plane counter to 4
  570. @@PlaneLoop:
  571.         push  di                          ; Save bitmap's start dest. offset
  572.         mov   bl,[BMHeight]               ; Reset row counter (BL)
  573.         mov   al,bh
  574.         out   dx,al                       ; set vga write plane
  575. @@RowLoop:
  576.     mov   cl,[Columns]                ; Reset Column counter cl
  577.         shr   cx,1
  578.         jnc   @@ColLoop
  579.         lodsb
  580.         mov   es:[di],al
  581.     dec   di
  582. @@ColLoop:
  583.     lodsw                             ; Get next source bitmap byte
  584.         xchg  al,ah
  585.     mov   es:[di],ax
  586.     sub   di,2
  587.     loop  @@ColLoop                   ; loop if more columns left
  588.  
  589.     add   di,[LineInc]                ; Move to next row
  590.         dec   bl                          ; decrement row counter
  591.         jnz   @@RowLoop                   ; Jump if more rows left
  592.         pop   di                          ; Restore bitmaps start dest byte
  593.         ror   bh,1                        ; Shift mask for next plane
  594.     sbb   di,0                        ; If wrapped increment dest address
  595.     dec   [Plane]                     ; Decrement plane counter
  596.         jnz   @@PlaneLoop                 ; Jump if more planes left
  597.  
  598.         pop   ds                          ; restore data segment
  599.         pop   di                          ; restore registers
  600.         pop   si
  601.         mov   sp,bp                       ; dealloc local variables
  602.         pop   bp
  603.         ret